import { Empty, Tree, TreeProps } from 'antd';
import type { DataNode } from 'antd/lib/tree';
import { cloneDeep } from 'lodash-es';
import type { ReactNode } from 'react';
import { FC } from 'react';

export interface TreeBindProps<T> {
  key?: keyof T | ((data: T) => string);
  title?: keyof T | ((data: T) => string);
  value?: keyof T | ((data: T) => string);
  children?: keyof T;
  isLeaf?: keyof T | ((data: T) => boolean);
  disabled?: keyof T | ((data: T) => boolean);
  selectable?: keyof T | ((data: T) => boolean);
  checkable?: keyof T | ((data: T) => boolean);
  disableCheckbox?: keyof T | ((data: T) => boolean);
}
export interface BaseTreeProps<T extends Record<string, any> = Record<string, any>>
  extends Omit<TreeProps, 'treeData' | 'titleRender'> {
  treeData?: T[];
  titleRender?: (node: DataNode & T) => ReactNode;
  bindProps?: TreeBindProps<T>;
}

/**
 *
 * @param originTreeItem
 * @param treeItem
 * @param bindKey
 * @param propKey
 */
function setTreeItem(originTreeItem: any, treeItem: any, bindKey: string, propKey: any) {
  if (propKey) {
    treeItem[bindKey] = propKey instanceof Function ? propKey(originTreeItem) : treeItem[propKey];
  }
}
/**
 *
 * @param props
 * @returns
 */
const BaseTree: FC<BaseTreeProps> = (props) => {
  const { treeData = [], titleRender, bindProps = {}, ...restProps } = props;
  const {
    key = 'key',
    title = 'title',
    value,
    children = 'children',
    isLeaf,
    disabled,
    selectable,
    checkable,
    disableCheckbox
  } = bindProps;
  const treeDataFormate = (data: any[]) =>
    data.map((treeItem) => {
      const item = cloneDeep(treeItem);
      setTreeItem(treeItem, item, 'key', key);
      setTreeItem(treeItem, item, 'title', title);
      setTreeItem(treeItem, item, 'value', value);
      setTreeItem(treeItem, item, 'isLeaf', isLeaf);
      setTreeItem(treeItem, item, 'disabled', disabled);
      setTreeItem(treeItem, item, 'selectable', selectable);
      setTreeItem(treeItem, item, 'checkable', checkable);
      setTreeItem(treeItem, item, 'disableCheckbox', disableCheckbox);
      if (item[children]?.length) item.children = treeDataFormate(item[children]);
      return item;
    });
  return treeData.length > 0 ? (
    <Tree
      {...restProps}
      titleRender={titleRender as TreeProps['titleRender']}
      treeData={treeDataFormate(treeData)}
    />
  ) : (
    <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  );
};

export default BaseTree;
